
#include "main.h"


u8 Pkt_CmdProc(u8 uart, u8 cmd, u8 dev, u16 *pdlen, u8 *pdata)
{
	static FWDATA_DATA _fwData = {0,};
	static u32 _uFlashDst = APP_START_ADDRESS;

	switch (cmd)
	{
	case CMD_INIT:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pOsType = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_INIT : %d\r\n", dev, *pOsType);
			#endif	//DBG_MSG_PKT

			g_u8OsType = *pOsType;

#if		defined(BSP_DEVICE_TOUCH)
			{
				u8 bReset = RESET_APP;
				for (u8 uart=eUART_MIN; uart<eUART_MAX; uart++)
					Uart_PktCmd(uart, CMD_RESET, (DEV_CAMERA1 + uart), 1, (u8 *)&bReset);
			}
#endif	//BSP_DEVICE_TOUCH

			*pdata = g_u8CurState;
			*(pdata + 1) = g_u8MyAddr;

			*pdlen = 2;
		}
		break;

	case CMD_RESET:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pReset = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_RESET : %d\r\n", dev, *pReset);
			#endif	//DBG_MSG_PKT

#if		defined(BSP_DEVICE_TOUCH)
			{
				u8 bReset = RESET_APP;
				for (u8 uart=eUART_MIN; uart<eUART_MAX; uart++)
					Uart_PktCmd(uart, CMD_RESET, (DEV_CAMERA1 + uart), 1, (u8 *)&bReset);
			}
#endif	//BSP_DEVICE_TOUCH

			if (RESET_IAP == *pReset)
				Util_ResetWWDG();
			else// if (RESET_APP == bResets)
				NVIC_SystemReset();

			*pdlen = 0;
		}
		break;

	case CMD_GET_VERSION:
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_GET_VERSION : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			*pdlen = sizeof(VERSION_DATA);
			{
				PVERSION_DATA pData = (PVERSION_DATA)pdata;
				pData->wVersion = MODULE_VERSION;
				pData->dwBuildTime = Util_GetBuildTime();
			}
		}
		break;

	case CMD_UPGRADE_FWINFO:
		if (sizeof(FWINFO_DATA) != *pdlen)
			return ERR_LENGTH_DATA;
		{
			PFWINFO_DATA pData = (PFWINFO_DATA)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_UPGRADE_INFO : %d %d\r\n", dev, pData->bType, pData->wTotalSize);
			#endif	//DBG_MSG_PKT

			_fwData.wTotalSize = pData->wTotalSize;
			_fwData.wCurSize = 0;

			if (FWTYPE_IAP == pData->bType)
			{
				_uFlashDst = IAP_START_ADDRESS;
				FLASH_If_Erase(_uFlashDst, IAP_END_ADDRESS);
			}
			else if (FWTYPE_APP == pData->bType)
			{
				_uFlashDst = APP_START_ADDRESS;
				FLASH_If_Erase(_uFlashDst, APP_END_ADDRESS);
			}
			else if (FWTYPE_SAVE_APP == pData->bType)
			{
				_uFlashDst = SAVE_APP_START_ADDRESS;
				FLASH_If_Erase(_uFlashDst, SAVE_APP_END_ADDRESS);
			}
			else if (FWTYPE_SAVE_IAP == pData->bType)
			{
				_uFlashDst = SAVE_IAP_START_ADDRESS;
				FLASH_If_Erase(_uFlashDst, SAVE_IAP_END_ADDRESS);
			}
		}
		break;
	case CMD_UPGRADE_FWDATA:
		if (*pdlen)
		{
			u32 ramsource = (u32)pdata;
			#if	DBG_MSG_PKT
			//printf("%d-CMD_UPGRADE_DATA : %d\r\n", dev, *pdlen);
			#endif	//DBG_MSG_PKT

			FLASH_If_Write(&_uFlashDst, (u32 *)ramsource, (u16)(*pdlen / 4));
			_fwData.wCurSize += *pdlen;
			if (_fwData.wTotalSize <= _fwData.wCurSize)
			{
				if ((SAVE_APP_START_ADDRESS < _uFlashDst) && ((SAVE_APP_START_ADDRESS+0x20000) > _uFlashDst))
				{
					EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_APP_CHECK], 0x1234);
					EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_APP_TOTAL_SIZE], _fwData.wTotalSize);
				}
				else if ((SAVE_IAP_START_ADDRESS < _uFlashDst) && ((SAVE_IAP_START_ADDRESS+0x20000) > _uFlashDst))
				{
					EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_IAP_CHECK], 0x1234);
					EE_WriteVariable(g_VirtAddVarTab[IAP_SAVE_IAP_TOTAL_SIZE], _fwData.wTotalSize);
				}
			}
			#if	DBG_MSG_PKT
			if (_fwData.wTotalSize > _fwData.wCurSize)	printf(".");	//printf("%d,", _fwData.wCurSize);
			else										printf("\r\n");	//printf("%d\r\n", _fwData.wCurSize);
			#endif	//DBG_MSG_PKT

			*pdlen = sizeof(_fwData);
			memcpy(pdata, &_fwData, *pdlen);
		}
		break;;

	case CMD_GET_STATE:
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_GET_STATE : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			*pdlen = 1;
			*pdata = g_u8CurState;
		}
		break;
	case CMD_SET_STATE:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			g_u8CurState = *pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_STATE : %d\r\n", dev, g_u8CurState);
			#endif	//DBG_MSG_PKT
		}
		break;
	case CMD_SET_BUZZER:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_BUZZER : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

#if		defined(BSP_DEVICE_TOUCH)
			g_u32BuzzerDelay = g_vu32SysTickCount + (*pdata * 10);	// *[10msec]
			Led_Set(eLED_BUZZER, 1);
#endif	//BSP_DEVICE_TOUCH

			*pdlen = 0;
		}
		break;
	case CMD_FLASH_ERASE:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			u32 Address = 0;
			#if	DBG_MSG_PKT
			printf("%d-CMD_FLASH_ERASE : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT
			switch (*pData)
			{
			case 0:	Address = ADDR_FLASH_SECTOR_0;	break;
			case 1:	Address = ADDR_FLASH_SECTOR_1;	break;
			case 2:	Address = ADDR_FLASH_SECTOR_2;	break;
			case 3:	Address = ADDR_FLASH_SECTOR_3;	break;
			case 4:	Address = ADDR_FLASH_SECTOR_4;	break;
			case 5:	Address = ADDR_FLASH_SECTOR_5;	break;
			case 6:	Address = ADDR_FLASH_SECTOR_6;	break;
			case 7:	Address = ADDR_FLASH_SECTOR_7;	break;
			}
			if (Address)
			{
				FLASH_If_Erase(Address, Address);
			}
		}
		break;
	case CMD_EEPROM_READ:
		if (sizeof(EEPROM_DATA) != *pdlen)
			return ERR_LENGTH_DATA;
		{
			PEEPROM_DATA pData = (PEEPROM_DATA)pdata;
			if (ENDOF_EEPROM > pData->wAddress)
			{
				u16 uData;
				EE_ReadVariable(g_VirtAddVarTab[pData->wAddress], &uData);
				pData->wData = uData;
			}
			#if	DBG_MSG_PKT
			printf("%d-CMD_EEPROM_READ : (%d %d)\r\n", dev, pData->wAddress, pData->wData);
			#endif	//DBG_MSG_PKT
		}
		break;
	case CMD_EEPROM_WRITE:
		if (sizeof(EEPROM_DATA) != *pdlen)
			return ERR_LENGTH_DATA;
		{
			PEEPROM_DATA pData = (PEEPROM_DATA)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_EEPROM_WRITE : (%d %d)\r\n", dev, pData->wAddress, pData->wData);
			#endif	//DBG_MSG_PKT
			if (ENDOF_EEPROM > pData->wAddress)
			{
				u16 uData = pData->wData;
				EE_WriteVariable(g_VirtAddVarTab[pData->wAddress], uData);
			}
		}
		break;
		
	case CMD_TEST_CODE:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_TEST_CODE : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_u8TestCode = *pData;
		}
		break;

#if		defined(BSP_APP)
#if		defined(BSP_DEVICE_TOUCH)
	case CMD_TOUCH_PING:
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_TOUCH_PING : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			*pdata = g_u8CurState;

			*pdlen = 1;
		}
		break;
	case CMD_GET_TOUCH_CONFIG:
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_GET_TOUCH_CONFIG : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			memcpy(pdata, &g_TCD, sizeof(g_TCD));

			*pdlen = sizeof(g_TCD);
		}
		break;
	case CMD_SET_TOUCH_CONFIG:
		if ((sizeof(TOUCHCONFIG_DATA) != *pdlen) && (0 != *pdlen))
			return ERR_LENGTH_DATA;
		{
			if (*pdlen)
			{
				PTOUCHCONFIG_DATA pData = (PTOUCHCONFIG_DATA)pdata;
				memcpy(&g_TCD, pData, *pdlen);
			}
			else
			{
				g_TCD.bFilterNum = DATA_FILTER_NUM_DEF;
				g_TCD.bInputMode = DATA_INPUT_MODE_MULTI;
				for (u8 i=0; i<DATA_PWM_NUM; i++) {
					g_TCD.bPWMs[i] = DATA_PWM_DEF;
				}
				g_TCD.bTimeTap = DATA_TIME_TAP_DEF;
				g_TCD.bTimeLTap = DATA_TIME_LTAP_DEF;
				g_TCD.bAreaTap = DATA_AREA_TAP_DEF;
				g_TCD.bAreaDTap = DATA_AREA_DTAP_DEF;
				g_TCD.bAreaPalm = DATA_AREA_PALM_DEF;
				g_TCD.bBeepAlert = DATA_BEEP_ALERT_DEF;
				g_TCD.bBeepClick = DATA_BEEP_CLICK_DEF;
				g_TCD.bTouchNoSend = DATA_TOUCH_NOSEND_DEF;

				*pdlen = sizeof(g_TCD);
				memcpy(pdata, &g_TCD, *pdlen);
			}
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_TOUCH_CONFIG : (%d %d) (%d %d %d %d) (%d %d) (%d %d %d) (%d %d) (%d)\r\n", dev,
				g_TCD.bFilterNum, g_TCD.bInputMode,
				g_TCD.bPWMs[0], g_TCD.bPWMs[1], g_TCD.bPWMs[2], g_TCD.bPWMs[3],
				g_TCD.bTimeTap, g_TCD.bTimeLTap,
				g_TCD.bAreaTap, g_TCD.bAreaDTap, g_TCD.bAreaPalm,
				g_TCD.bBeepAlert, g_TCD.bBeepClick,
				g_TCD.bTouchNoSend);
			#endif	//DBG_MSG_PKT

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_FILTER_NUM], g_TCD.bFilterNum);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_INPUT_MODE], g_TCD.bInputMode);
			for (u8 i=0; i<DATA_PWM_NUM; i++) {
				g_TCD.bPWMs[i] = Pwm_Set(i, g_TCD.bPWMs[i]);
				EE_WriteVariable(g_VirtAddVarTab[TOUCH_PWM_CH1 + i], g_TCD.bPWMs[i]);
			}
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TIME_TAP], g_TCD.bTimeTap);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TIME_LTAP], g_TCD.bTimeLTap);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_TAP], g_TCD.bAreaTap);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_DTAP], g_TCD.bAreaDTap);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_PALM], g_TCD.bAreaPalm);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_BEEP_ALERT], g_TCD.bBeepAlert);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_BEEP_CLICK], g_TCD.bBeepClick);
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TOUCH_NOSEND], g_TCD.bTouchNoSend);

			g_fAreaTap = g_TCD.bAreaTap * 0.001;	//[*0.1 %]
			g_fAreaDTap = g_TCD.bAreaDTap * 0.001;	//[*0.1 %]
			g_fAreaPalm = g_TCD.bAreaPalm * 0.001;	//[*0.1 %]
		}
		break;
	case CMD_SET_TOUCH_FILTER:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_SET_TOUCH_FILTER : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bFilterNum = *pData;

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_FILTER_NUM], g_TCD.bFilterNum);
		}
		break;
	case CMD_SET_INPUT_MODE:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_SET_INPUT_MODE : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			if (DATA_INPUT_MODE_MULTI < *pData)
				*pData = DATA_INPUT_MODE_MOUSE;
			g_TCD.bInputMode = *pData;
	
			EE_WriteVariable(g_VirtAddVarTab[TOUCH_INPUT_MODE], g_TCD.bInputMode);
		}
		break;
	case CMD_SET_PWMS:
		if (4 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_PWMS : (%d %d %d %d)\r\n", dev, pData[0], pData[1], pData[2], pData[3]);
			#endif	//DBG_MSG_PKT

			for (u8 i=0; i<DATA_PWM_NUM; i++) {
				g_TCD.bPWMs[i] = Pwm_Set(i, pData[i]);
				EE_WriteVariable(g_VirtAddVarTab[TOUCH_PWM_CH1 + i], g_TCD.bPWMs[i]);
			}
		}
		break;
	case CMD_SET_TIME_TAP:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_SET_TIME_TAP : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bTimeTap = *pData;
			g_u32TimeTap = g_TCD.bTimeTap * 100;	//[*100 msec]

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TIME_TAP], g_TCD.bTimeTap);
		}
		break;
	case CMD_SET_TIME_LTAP:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_SET_TIME_LTAP : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bTimeLTap = *pData;
			g_u32TimeLTap = g_TCD.bTimeLTap * 100;	//[*100 msec]

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TIME_LTAP], g_TCD.bTimeLTap);
		}
		break;
	case CMD_SET_AREA_TAP:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_AREA_TAP : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bAreaTap = *pData;
			g_fAreaTap = g_TCD.bAreaTap * 0.001;	//[*0.1 %]

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_TAP], g_TCD.bAreaTap);
		}
		break;
	case CMD_SET_AREA_DTAP:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_AREA_DTAP : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bAreaDTap = *pData;
			g_fAreaDTap = g_TCD.bAreaDTap * 0.001;	//[*0.1 %]

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_DTAP], g_TCD.bAreaDTap);
		}
		break;
	case CMD_SET_AREA_PALM:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_AREA_PALM : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bAreaPalm = *pData;
			g_fAreaPalm = g_TCD.bAreaPalm * 0.001;	//[*0.1 %]

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_AREA_PALM], g_TCD.bAreaPalm);
		}
		break;
	case CMD_SET_BEEP_ALERT:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_BEEP_ALERT : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bBeepAlert = *pData;

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_BEEP_ALERT], g_TCD.bBeepAlert);
		}
		break;
	case CMD_SET_BEEP_CLICK:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_BEEP_CLICK : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bBeepClick = *pData;

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_BEEP_CLICK], g_TCD.bBeepClick);
		}
		break;
	case CMD_SET_TOUCH_NOSEND:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = (u8 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_TOUCH_NOSEND : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_TCD.bTouchNoSend = *pData;

			EE_WriteVariable(g_VirtAddVarTab[TOUCH_TOUCH_NOSEND], g_TCD.bTouchNoSend);
		}
		break;

	case CMD_GET_TOUCH_GESTURE://	0x51	// none / gesture_data(struct) - only touch
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_GET_TOUCH_GESTURE : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			memcpy(pdata, &g_GD, sizeof(g_GD));

			*pdlen = sizeof(g_GD);
		}
		break;
	case CMD_SET_TOUCH_GESTURE://	0x52	// gesture_data(struct) / gesture_data(struct) - only touch
		if ((sizeof(GESTURE_DATA) != *pdlen) && (0 != *pdlen))
			return ERR_LENGTH_DATA;
		{
			if (*pdlen)
			{
				PGESTURE_DATA pData = (PGESTURE_DATA)pdata;
				memcpy(&g_GD, pData, *pdlen);
			}
			else
			{
				memset(&g_GD, 0, sizeof(g_GD));

				*pdlen = sizeof(g_GD);
				memcpy(pdata, &g_GD, *pdlen);
			}
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_TOUCH_GESTURE(Hex) : (%X %X) (%X %X) (%X %X) (%X %X) (%X %X) (%X %X) (%X %X)\r\n", dev,
				g_GD.g[GE_DRAGUP].bFlag, g_GD.g[GE_DRAGUP].bKey,
				g_GD.g[GE_DRAGRIGHT].bFlag, g_GD.g[GE_DRAGRIGHT].bKey,
				g_GD.g[GE_DRAGDOWN].bFlag, g_GD.g[GE_DRAGDOWN].bKey,
				g_GD.g[GE_DRAGLEFT].bFlag, g_GD.g[GE_DRAGLEFT].bKey,
				g_GD.g[GE_TAP].bFlag, g_GD.g[GE_TAP].bKey,
				g_GD.g[GE_TAPDOUBLE].bFlag, g_GD.g[GE_TAPDOUBLE].bKey,
				g_GD.g[GE_TAPLONG].bFlag, g_GD.g[GE_TAPLONG].bKey);
			#endif	//DBG_MSG_PKT

			u16 uData;
			memcpy(&uData, &g_GD.g[GE_DRAGUP], 2);		EE_WriteVariable(g_VirtAddVarTab[GESTURE_UDRAG], uData);
			memcpy(&uData, &g_GD.g[GE_DRAGRIGHT], 2);	EE_WriteVariable(g_VirtAddVarTab[GESTURE_RDRAG], uData);
			memcpy(&uData, &g_GD.g[GE_DRAGDOWN], 2);	EE_WriteVariable(g_VirtAddVarTab[GESTURE_DDRAG], uData);
			memcpy(&uData, &g_GD.g[GE_DRAGLEFT], 2);	EE_WriteVariable(g_VirtAddVarTab[GESTURE_LDRAG], uData);
			memcpy(&uData, &g_GD.g[GE_TAP], 2);			EE_WriteVariable(g_VirtAddVarTab[GESTURE_TAP], uData);
			memcpy(&uData, &g_GD.g[GE_TAPDOUBLE], 2);	EE_WriteVariable(g_VirtAddVarTab[GESTURE_DTAP], uData);
			memcpy(&uData, &g_GD.g[GE_TAPLONG], 2);		EE_WriteVariable(g_VirtAddVarTab[GESTURE_LTAP], uData);
		}
		break;

#elif	defined(BSP_DEVICE_CAMERA)
	case CMD_GET_CAMERA_CONFIG:
		if (0 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			#if	DBG_MSG_PKT
			printf("%d-CMD_GET_CAMERA_CONFIG : none\r\n", dev);
			#endif	//DBG_MSG_PKT

			*pdlen = sizeof(g_CCD);
			memcpy(pdata, &g_CCD, *pdlen);
		}
		break;
	case CMD_SET_CAMERA_CONFIG:
		if ((sizeof(CAMERACONFIG_DATA) != *pdlen) && (0 != *pdlen))
			return ERR_LENGTH_DATA;
		{
			if (*pdlen)
			{
				PCAMERACONFIG_DATA pData = (PCAMERACONFIG_DATA)pdata;
				memcpy(&g_CCD, pData, *pdlen);
			}
			else
			{
				g_CCD.nYCenter = DATA_YCENTER_DEF;
				g_CCD.wXStart = DATA_XSTART_DEF;
				g_CCD.wXEnd = DATA_XEND_DEF;
				g_CCD.bThreshold = DATA_THRESHOLD_DEF;
				g_CCD.bMinWidth = DATA_MINWIDTH_DEF;
				g_CCD.bAverageLight = DATA_AVERAGELIGHT_DEF;
				for (u8 i=0; i<DATA_COEFFS_NUM; i++) {
					g_CCD.fCoeffs[i] = 0;
				}

				*pdlen = sizeof(g_CCD);
				memcpy(pdata, &g_CCD, *pdlen);
			}
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_CAMERA_CONFIG : (%d %d %d %d %d %d) (%f %f %f %f %f %f %f %f)\r\n", dev,
				g_CCD.nYCenter, g_CCD.wXStart, g_CCD.wXEnd, g_CCD.bThreshold,
				g_CCD.bMinWidth, g_CCD.bAverageLight,
				g_CCD.fCoeffs[0], g_CCD.fCoeffs[1], g_CCD.fCoeffs[2], g_CCD.fCoeffs[3],
				g_CCD.fCoeffs[4], g_CCD.fCoeffs[5], g_CCD.fCoeffs[6], g_CCD.fCoeffs[7]);
			#endif	//DBG_MSG_PKT

			EE_WriteVariable(g_VirtAddVarTab[CAMERA_YCENTER], g_CCD.nYCenter);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_XSTART], g_CCD.wXStart);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_XEND], g_CCD.wXEnd);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_THRESHOLD], g_CCD.bThreshold);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_MINWIDTH], g_CCD.bMinWidth);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_AVERAGELIGHT], g_CCD.bAverageLight);
			for (int i=0; i<DATA_COEFFS_NUM; i++) {
				float fValue = g_CCD.fCoeffs[i];
				u32 uValue = *(u32 *)&fValue;
				EE_WriteVariable(g_VirtAddVarTab[CAMERA_COEFFS_L0+(i<<1)], LOWORD(uValue));
				EE_WriteVariable(g_VirtAddVarTab[CAMERA_COEFFS_H0+(i<<1)], HIWORD(uValue));
			}
		}
		break;
	case CMD_SET_YCENTER:
		if (2 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			s16 *pData = (s16 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_YCENTER : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			Cmos_ChangeYCenter(*pData);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_YCENTER], g_CCD.nYCenter);
		}
		break;
	case CMD_SET_XSTART:
		if (2 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u16 *pData = (u16 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_XSTART : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			Cmos_ChangeXStart(*pData);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_XSTART], g_CCD.wXStart);
		}
		break;
	case CMD_SET_XEND:
		if (2 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u16 *pData = (u16 *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_XEND : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			Cmos_ChangeXEnd(*pData);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_XEND], g_CCD.wXEnd);
		}
		break;
	case CMD_SET_THRESHOLD:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_THRESHOLD : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			Cmos_ChangeThreshold(*pData);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_THRESHOLD], g_CCD.bThreshold);
		}
		break;
	case CMD_SET_MINWIDTH:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_MINWIDTH : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_CCD.bMinWidth = max(min(*pData, DATA_MINWIDTH_MAX), DATA_MINWIDTH_MIN);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_MINWIDTH], g_CCD.bMinWidth);
		}
		break;
	case CMD_SET_AVERAGELIGHT:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_AVERAGELIGHT : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			g_CCD.bAverageLight = max(min(*pData, DATA_AVERAGELIGHT_MAX), DATA_AVERAGELIGHT_MIN);
			EE_WriteVariable(g_VirtAddVarTab[CAMERA_AVERAGELIGHT], g_CCD.bAverageLight);
		}
		break;
	case CMD_SET_COEFFS:
		if (sizeof(float)*DATA_COEFFS_NUM != *pdlen)
			return ERR_LENGTH_DATA;
		{
			float *pData = (float *)pdata;
			#if	DBG_MSG_PKT
			printf("%d-CMD_SET_COEFFS : (%f %f %f %f %f %f %f %f)\r\n", dev,
				pData[0], pData[1], pData[2], pData[3], pData[4], pData[5], pData[6], pData[7]);
			#endif	//DBG_MSG_PKT

			for (int i=0; i<DATA_COEFFS_NUM; i++) {
				float fValue = g_CCD.fCoeffs[i] = pData[i];
				u32 uValue = *(u32 *)&fValue;
				EE_WriteVariable(g_VirtAddVarTab[CAMERA_COEFFS_L0+(i<<1)], LOWORD(uValue));
				EE_WriteVariable(g_VirtAddVarTab[CAMERA_COEFFS_H0+(i<<1)], HIWORD(uValue));
			}
		}
		break;

	case CMD_SIDEVIEW_START:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_SIDEVIEW_START : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			*pData = Cmos_SideviewStart(*pData);
		}
		break;
	case CMD_DETECTION_START:
		if (1 != *pdlen)
			return ERR_LENGTH_DATA;
		{
			u8 *pData = pdata;
			#if DBG_MSG_PKT
			printf("%d-CMD_DETECTION_START : %d\r\n", dev, *pData);
			#endif	//DBG_MSG_PKT

			*pData = Cmos_DetectionStart(*pData);
		}
		break;

#endif	//BSP_DEVICE_xxx
#endif	//BSP_APP


	default:
		return ERR_UNKNOWN_COMMAND;
	}

	return ERR_SUCCESS;
}

